<template>
    <a-modal
        v-model:visible="showModal"
        :title="title"
        :width="620"
        :destroyOnClose="true"
        :maskClosable="false"
        :confirmLoading="loading"
        @ok="onSubmit"
        @cancel="handleCancle"
    >
        <a-form class="menu-model" layout="horizontal" :model="formState" :key="formState.type" :rules="rules" ref="formRef">
            <a-form-item class="full-width" :label="t('yl.menuType')">
                <a-radio-group v-model:value="formState.type" button-style="solid">
                    <a-radio-button :value="0">{{ t('yl.catalogue') }}</a-radio-button>
                    <a-radio-button :value="1">{{ t('yl.menu') }}</a-radio-button>
                    <a-radio-button :value="2">{{ t('yl.button') }}</a-radio-button>
                </a-radio-group>
            </a-form-item>
            <a-form-item id="iconItem" class="full-width" :label="t('yl.menuIcon')" v-if="formState.type != 2" name="icon">
                <a-input v-model:value="formState.icon" readonly :placeholder="t('yl.inputIconStand')">
                    <template #prefix>
                        <search-outlined v-if="!formState.icon" :style="{ color: '#ccc' }"></search-outlined>
                        <component :is="formState.icon" v-if="formState.icon"></component>
                    </template>
                </a-input>
                <yl-menu-icons-vue :visible="showIconsModel" v-model:value="formState.icon"></yl-menu-icons-vue>
            </a-form-item>
            <a-form-item class="third-width" v-if="formState.type != 2" :label="t('yl.linkMenu')">
                <a-radio-group v-model:value="formState.iFrame" button-style="solid">
                    <a-radio-button :value="true">{{ t('yl.yes') }}</a-radio-button>
                    <a-radio-button :value="false">{{ t('yl.no') }}</a-radio-button>
                </a-radio-group>
            </a-form-item>
            <a-form-item class="third-width" v-if="formState.type == 1" :label="t('yl.menuCache')">
                <a-radio-group v-model:value="formState.cache" button-style="solid">
                    <a-radio-button :value="true">{{ t('yl.yes') }}</a-radio-button>
                    <a-radio-button :value="false">{{ t('yl.no') }}</a-radio-button>
                </a-radio-group>
            </a-form-item>
            <a-form-item class="third-width" v-if="formState.type != 2" :label="t('yl.menuVisible')">
                <a-radio-group v-model:value="formState.hidden" button-style="solid">
                    <a-radio-button :value="true">{{ t('yl.yes') }}</a-radio-button>
                    <a-radio-button :value="false">{{ t('yl.no') }}</a-radio-button>
                </a-radio-group>
            </a-form-item>
            <a-form-item :class="formState.type != 2 ? 'full-width' : 'half-width'" :label="t('yl.menuTitle')" name="title">
                <a-input v-model:value="formState.title" :placeholder="t('yl.inputNameStand')" />
            </a-form-item>
            <a-form-item class="half-width" :label="t('yl.routerPath')" v-if="formState.type != 2" name="path">
                <a-input v-model:value="formState.path" :placeholder="t('yl.inputNameStand')" />
            </a-form-item>
            <a-form-item class="half-width" :label="t('yl.menuSort')">
                <a-input-number v-model:value="formState.menuSort" :min="1" :max="999" />
            </a-form-item>
            <a-form-item
                v-if="formState.type != 0"
                :class="formState.type != 0 ? 'full-width' : 'half-width'"
                :label="t('yl.permission')"
            >
                <a-input v-model:value="formState.permission" :placeholder="t('yl.permission')" />
            </a-form-item>
            <!-- <a-form-item class="half-width" :label="t('yl.forUserType')">
                <a-select :placeholder="t('yl.forUserType')">
                    <a-select-option value="0">类型1</a-select-option>
                    <a-select-option value="1">类型2</a-select-option>
                    <a-select-option value="2">类型3</a-select-option>
                    <a-select-option value="3">类型4</a-select-option>
                </a-select>
            </a-form-item>
            <a-form-item class="half-width" :label="t('yl.forTrade')">
                <a-select :placeholder="t('yl.forTrade')">
                    <a-select-option value="0">行业1</a-select-option>
                    <a-select-option value="1">行业2</a-select-option>
                    <a-select-option value="2">行业3</a-select-option>
                    <a-select-option value="3">行业4</a-select-option>
                </a-select>
            </a-form-item> -->
            <a-form-item class="full-width" :label="t('yl.parentNode')">
                <a-tree-select
                    v-model:value="formState.pid"
                    style="width: 100%"
                    :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                    :tree-data="treeData"
                    :load-data="onLoadData"
                    :replaceFields="{
                        children: 'children',
                        title: 'label',
                        key: 'id',
                        value: 'id',
                    }"
                    placeholder="Please select"
                >
                </a-tree-select>
            </a-form-item>
        </a-form>
    </a-modal>
</template>

<script lang="ts">
import { defineComponent, computed, ref, reactive, toRefs, watch, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { SearchOutlined } from '@ant-design/icons-vue';
import useMenus from '@/hooks/useMenus';
import ylMenuIconsVue from '@/components/ylMenuIcons.vue';

export default defineComponent({
    name: 'menuModel',
    components: {
        SearchOutlined,
        ylMenuIconsVue,
    },
    props: {
        visible: {
            type: Boolean,
            default: () => false,
        },
        title: {
            type: String,
        },
        loading: {
            type: Boolean,
            default: () => false,
        },
        menu: {
            type: Object,
        },
    },
    setup(props, { emit }) {
        const { t } = useI18n();
        const showModal = computed(() => props.visible);
        // 表单数据
        const formState = reactive({
            type: 0, // 类型
            icon: '', // 图标
            iFrame: false, // 是否外链
            cache: false, // 是否缓存
            hidden: true, // 是否可见
            title: '', // 标题
            path: '', // 路由地址
            menuSort: 999, // 菜单排序
            pid: 0, // 上级节点
            id: null,
            permission: null,
        });

        // 表单校验
        const rules = reactive({
            icon: [
                {
                    required: computed(() => (formState.type == 2 ? false : true)),
                    message: t('yl.inputIconStand'),
                    trigger: 'blur',
                },
            ],
            title: [{ required: true, message: t('yl.inputMenuTitleStand'), trigger: 'blur' }],
            path: [{ required: true, message: t('yl.inputRouterPathStand'), trigger: 'blur' }],
            permission: [{ required: true, message: t('yl.permission'), trigger: 'blur' }],
        });
        const formRef = ref();

        // 提交
        const onSubmit = () => {
            formRef.value.validate().then(() => {
                emit('submit', formState);
            });
        };

        // 取消
        const handleCancle = () => {
            return emit('cancle');
        };

        // 编辑菜单
        watch(
            () => props.menu,
            (newValue) => {
                if (newValue) {
                    const { type, icon, iFrame, cache, hidden, title, path, menuSort, pid, id, permission } = newValue;

                    formState.type = type;
                    formState.icon = icon;
                    formState.iFrame = iFrame;
                    formState.cache = cache;
                    formState.hidden = hidden;
                    formState.title = title;
                    formState.path = path;
                    formState.menuSort = menuSort;
                    formState.pid = pid ? pid : id;
                    formState.id = id;
                    formState.permission = permission;
                }
            }
        );

        // 其他数据
        const state = reactive({
            treeData: [] as NormalObj[],
            showIconsModel: false,
        });
        // 获取部门节点树
        watch(
            () => props.visible,
            async (onShow) => {
                state.treeData = [];

                if (onShow && !state.treeData.length) {
                    const params = {
                        page: 0,
                        size: 99,
                    };

                    const { list } = await useMenus(params);
                    const rootNode = {
                        deptSort: 1,
                        enabled: true,
                        hasChildren: true,
                        id: 0,
                        label: 'Root',
                        isLeaf: false,
                        children: list.map((item) => {
                            return {
                                ...item,
                                isLeaf: item.leaf,
                            };
                        }),
                    };
                    state.treeData.push(rootNode);
                }
            }
        );
        // 异步加载树节点数据
        const onLoadData = (treeNode: NormalObj) => {
            return new Promise(async (resolve: (value?: unknown) => void) => {
                if (treeNode.dataRef.children) {
                    resolve();
                    return;
                }
                const params = {
                    pid: treeNode.eventKey,
                };
                let { list } = await useMenus(params);
                list = list.length
                    ? list.map((item: NormalObj) => {
                          return Object.assign({}, item, { isLeaf: (item as any).leaf });
                      })
                    : [];
                treeNode.dataRef.children = list;
                resolve();
            });
        };

        onMounted(() => {
            document.addEventListener('click', (e: Event) => {
                let iconItem = document.getElementById('iconItem');
                let iconsWrapper = document.getElementById('iconsWrapper');

                if (iconItem?.contains((e as any).target) || iconsWrapper?.contains((e as any).target)) {
                    state.showIconsModel = true;
                } else {
                    state.showIconsModel = false;
                }
            });
        });
        watch(
            () => formState.icon,
            () => {
                const t = setTimeout(() => {
                    state.showIconsModel = false;
                    formRef.value.clearValidate();
                }, 100);
            }
        );

        return {
            formRef,
            t,
            showModal,
            onSubmit,
            handleCancle,
            rules,
            formState,
            ...toRefs(state),
            onLoadData,
        };
    },
});
</script>

<style lang="scss" scoped>
.menu-model {
    @include flex;
    justify-content: space-between;
    flex-wrap: wrap;
    .ant-form-item {
        @include flex;
        :deep .ant-form-item-label {
            flex-basis: $formLabel;
        }
        :deep .ant-form-item-control-wrapper {
            flex: 1;
        }
        :deep .ant-input-number {
            width: 100%;
        }
    }
    .full-width {
        position: relative;
        width: 100%;
    }
    .half-width {
        width: calc(50% - 10px);
    }
    .third-width {
        flex: 1;
    }
}
</style>
